package lambdasinaction.chap8.my;

/**
 * 策略模式 策略模式代表了解决一类算法的通用解决方案，你可以在运行时选择使用哪种方案。 在第2章中你已经简略地了解过这种模式了，当时我们介绍了如何使用不同的条件（比如苹果的重量，或者颜色）
 * 来筛选库存中的苹果。你可以将这一模式应用到更广泛的领域，比如使用不同的标准来验证输入的有效性， 使用不同的方式来分析或者格式化输入。
 *
 * 策略模式包含三部分内容： - 一个代表某个算法的接口（它是策略模式的接口） - 一个或多个该接口的具体实现，它们代表了算法的多种实现（比如，实体类 ConcreteStrategyA 或者
 * ConcreteStrategyB） - 一个或多个使用策略对象的客户
 *
 * @author Fish
 * @since 0.0.1 2018/8/9 17:18
 */
public class MyStrategyMain {

  public static void main(String[] args) {
    // old
    Validator v1 = new Validator(new IsNumeric());
    System.out.println(v1.validate("aaaa"));
    Validator v2 = new Validator(new IsAllLowerCase());
    System.out.println(v2.validate("bbb"));

    // with lambdas
    Validator v3 = new Validator((String s) -> s.matches("\\d+"));
    System.out.println(v3.validate("aaaa"));
    Validator v4 = new Validator((String s) -> s.matches("[a-z]]+"));
    System.out.println(v4.validate("bbbb"));


  }

  /**
   * 我们假设你希望验证输入的内容是否根据标准进行了恰当的格式化（比如只包含小写字母或数字） 你可以从定义一个验证文本（以 String 的形式表示）的接口入手：
   */
  public interface ValidationStrategy {

    boolean execute(String s);
  }

  /**
   * 其次，你定义了该接口的一个或多个具体实现
   */
  static private class IsAllLowerCase implements ValidationStrategy {

    @Override
    public boolean execute(String s) {
      return s.matches("[a-z]+");
    }
  }

  static private class IsNumeric implements ValidationStrategy {

    @Override
    public boolean execute(String s) {
      return s.matches("\\d+");
    }
  }

  /**
   * 之后，你就可以在你的程序中使用这些略有差异的验证策略了
   */
  static private class Validator {
    private final ValidationStrategy strategy;

    public Validator(ValidationStrategy v) {
      this.strategy = v;
    }

    public boolean validate(String s) {
      return strategy.execute(s);
    }
  }

}
